package cn.south.campus.business.service.impl;

import cn.south.campus.business.mapper.GoodsCategoryMapper;
import cn.south.campus.business.model.constants.CacheKey;
import cn.south.campus.business.model.entity.GoodsCategory;
import cn.south.campus.business.model.req.GoodsCategoryReq;
import cn.south.campus.business.model.vo.GoodsCategoryVo;
import cn.south.campus.business.service.GoodsCategoryService;
import cn.south.campus.common.cache.CacheService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 二手商品分类表 服务实现类
 * </p>
 *
 * @author chow
 * @since 2024-11-13
 */
@Service
@AllArgsConstructor
public class GoodsCategoryServiceImpl extends ServiceImpl<GoodsCategoryMapper, GoodsCategory> implements GoodsCategoryService {

    private final GoodsCategoryMapper goodsCategoryMapper;

    private final CacheService cacheService;

    @Override
    public List<GoodsCategoryVo> tree(GoodsCategoryReq req) {
        LambdaQueryWrapper<GoodsCategory> wrapper = new LambdaQueryWrapper<GoodsCategory>().like(StringUtils.isNotBlank(req.getName()), GoodsCategory::getName, req.getName());
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectList(wrapper);
        return buildCategory(categoryList, 0L, req.getName());

    }

    @Override
    public void refresh() {
        boolean res = cacheService.deleteObject(CacheKey.CATEGORY);
        int retryTimes = 5;
        while (!res && retryTimes > 0) {
            res = cacheService.deleteObject(CacheKey.CATEGORY);
            retryTimes--;
        }
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectList(null);
        Map<String, GoodsCategory> categoryMap = categoryList.stream().collect(Collectors.toMap(item -> String.valueOf(item.getId()), x -> x));
        cacheService.setCacheMap(CacheKey.CATEGORY, categoryMap);
    }

    @Override
    public List<GoodsCategoryVo> showFirst() {
        LambdaQueryWrapper<GoodsCategory> wrapper = new LambdaQueryWrapper<GoodsCategory>().eq(GoodsCategory::getParentId, 0);
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectList(wrapper);
        return categoryList.stream().map(GoodsCategoryVo::convert).collect(Collectors.toList());
    }


    @PostConstruct
    public void init() {
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectList(null);
        Map<String, GoodsCategory> categoryMap = categoryList.stream().collect(Collectors.toMap(item -> String.valueOf(item.getId()), x -> x));
        cacheService.setCacheMap(CacheKey.CATEGORY, categoryMap);
    }

    private List<GoodsCategoryVo> buildCategory(List<GoodsCategory> categoryList, long parentId, String name) {
        //搜索条件
        if (StringUtils.isNotEmpty(name)) {
            for (GoodsCategory category : categoryList) {
                if (category.getParentId().equals(parentId)) {
                    return categoryList.stream().map(x -> getGoodsCategoryListVo(parentId, x)).collect(Collectors.toList());
                }
            }
            return categoryList.stream().filter(goodsCategory -> !goodsCategory.getParentId().equals(parentId)).
                    map(x -> getGoodsCategoryListVo(parentId, x)).collect(Collectors.toList());
        }
        //遍历所有 找出所有父级
        List<GoodsCategoryVo> list = categoryList.stream().
                filter(goodsCategory -> goodsCategory.getParentId().equals(parentId)).
                map(x -> getGoodsCategoryListVo(parentId, x)).collect(Collectors.toList());
        //遍历父级
        for (GoodsCategoryVo parentMenus : list) {
            List<GoodsCategoryVo> goodsCategoryListVos = buildCategory(categoryList, parentMenus.getId(), name);
            if (goodsCategoryListVos.size() > 0) {
                //将子加入到父级下面
                parentMenus.setChildren(goodsCategoryListVos);
            }
        }
        return list;
    }

    private GoodsCategoryVo getGoodsCategoryListVo(Long parentId, GoodsCategory x) {
        GoodsCategoryVo goodsCategoryVo = new GoodsCategoryVo();
        goodsCategoryVo.setName(x.getName());
        goodsCategoryVo.setLevel(x.getLevel());
        goodsCategoryVo.setSort(x.getSort());
        goodsCategoryVo.setId(x.getId());
        goodsCategoryVo.setParentId(parentId);
        return goodsCategoryVo;
    }
}
